home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
c
/
cug190.zip
/
BC.C
< prev
next >
Wrap
Text File
|
1985-11-15
|
17KB
|
861 lines
/******************************************************************
bc.c, code building function of as68 assembler
*/
/* (C) Copyright 1982 Steve Passe */
/* All Rights Reserved */
/* version 1.00 */
/* created 10/21/82 */
/* version 1.01
8/30/83 ver. 1.01 modified for Aztec ver. 1.05g smp
*/
/* begincode */
/* includes */
#define AZTECZII 1
#ifndef AZTECZII
#include <stdio.h>
#else
#include "stdio.h" /* with aztecII compiler */
#endif
#include "b:as68.h"
/* externals */
extern char pass; /* present pass number, 1 or 2 */
extern unsigned line_count; /* line number of source file */
extern long loc_counter; /* address to assemble obj code */
extern int loc_plus; /* increment to loc counter */
extern FLAG abs_long; /* default to absolute long add.*/
extern FLAG rorg; /* in pc relative mode */
extern char label[32]; /* buffer for label from preparse */
extern char instr[33]; /* buffer for mnem, psdo or macro */
extern struct _mtable mtable[]; /* mnemonic lookup table */
extern struct _mvalue mvalue[]; /* mnemonic code table */
extern struct _oprnd op1, op2; /* structs to hold operand val */
extern char code[]; /* code array */
p1_mnem(mt)
struct _mtable *mt;
{
int result, index;
if ((index = match(mt)) == ERROR) {
/** flush error stack someday? */
return ERROR;
}
switch (result = mvalue[index]._opc_len) { /* determine code length... */
case 1:
case 2:
case 3:
break;
case 12: /* _imd not contained in opcode */
case 13:
result -= 10; /* strip '10' flag */
result += p1_codelen(&op2); /* add second operand length */
break;
case 0: /* gotta figure it out */
if (/**rorg**/ op1._rel_lbl && mvalue[index]._optyp1 == _sadr
&& (op1._typ == _address || op1._typ == _d16_ani)) {
result = 2 + p1_codelen(&op2); /* 1 for opcode, 1 for raddr */
}
else result = p1_codelen(&op1) + p1_codelen(&op2) + 1; /* 1 for code */
break;
}
loc_plus = result * 2;
return result;
}
p1_codelen(op)
struct _oprnd *op;
{
int result;
switch (op->_typ) {
case _address:
result = (op->_long_val) ? 2 : 1;
break;
case _d16_ani:
case _d8_anx:
case _labeli:
case _reglst:
case _label: /* needed? */
result = 1;
break;
default:
result = 0;
}
return result;
}
p2_mnem(mt)
struct _mtable *mt;
{
register int x; /* scratch */
int index ; /* index to mvalue */
int result;
for (x = 0; x < 10; ++x) { /* init code array to 0 */
code[x] = 0;
}
if ((index = match(mt)) == ERROR) {
dump_code(CODE, code, 0);
return ERROR;
}
code[0] = mvalue[index]._opcb1; /* get opcode */
code[1] = mvalue[index]._opcb2; /* get opcode */
if ((result = (*mvalue[index]._p2_action)()) < 0) { /* call funct */
err_out(result);
loc_plus = 0;
}
else loc_plus = ++result * 2; /* bytes created */
dump_code(CODE, code, loc_plus); /* send them */
return result; /* words created */
}
match(mt)
struct _mtable *mt;
{
int index; /* index to mvalue */
int type1, type2; /* operand types */
if ((type1 = op_eval(&op1)) < 0) { /* legal type found? */
err_out(BAD_OP1); /* first op bad */
}
if ((type2 = op_eval(&op2)) < 0) { /* second op? */
err_out(BAD_OP2); /* no good */
}
if (type1 < 0 || type2 < 0) {
return ERROR; /* use NULL opcode */
}
if ((index = type_search(mt, type1, type2)) <=0) {
switch (index) {
case ILGL_OP1:
err_out(ILGL_OP1); /* no good */
return ERROR;
case ILGL_OP2:
err_out(ILGL_OP2); /* no good */
return ERROR;
default:
return ERROR;
}
}
return index;
}
type_search(mt, type1, type2)
struct _mtable *mt;
int type1;
int type2;
{
register int x, y; /* count and index */
char t1, t2; /* temp for array value */
for (x = mt->_mvc, y = mt->_mvi; x; --x, ++y) { /* search */
/* find op1 match... */
if (((t1 = mvalue[y]._optyp1) == type1) /* if exact match */
|| ((!(t1 & ~0xf0)) && (t1 & type1))) { /* or classtyp and match */
/* search for second match */
for ( ; (mvalue[y]._optyp1 == t1) && x; --x, ++y) {
if (((t2 = mvalue[y]._optyp2) == type2) /* 2nd matches */
|| ((!(t2 & ~0xf0)) && (t2 & type2))) { /* or typ & match */
return y; /* found a match */
}
}
return ILGL_OP2;
}
}
return ILGL_OP1;
}
/* mask 3 bit immediate data from op1 over bits 3-1 of code [0] */
bbb(op)
struct _oprnd *op;
{
if (op->_data & ~7) return ERR_BBB;
code[0] |= (op->_data << 1);
return NULL;
}
/* first ext word holds bit number (7/31) from first operand */
bbbx(size, op)
int size;
struct _oprnd *op;
{
switch (size) {
case 3:
if (op->_data & ~7L) return ERR_BX3; /* range? */
case 5:
if (op->_data & ~31L) return ERR_BX5;
code[3] = op->_data;
return 1; /* 1 ext word */
default:
return ERR_BX;
}
}
/** mask bits 3-1 of first byte with op1, 8 = 00 */
ccc(op)
struct _oprnd *op;
{
if (op->_data < 1L || op->_data > 8L) return ERR_CCC;
code[0] |= (op->_data << 1) & 0x0f;
/** if (op->_data != 8L) code[0] |= op->_data << 1; **/
return NULL; /* no words added */
}
/* mask bits 3-1 of first byte, or bits 2-0 of second, with op reg */
rsd(byt, op)
int byt;
struct _oprnd *op;
{
code[byt] |= (byt) ? op->_reg : op->_reg << 1;
return NULL;
}
/* register mask list from op into ext */
mmkk(order, op)
char order;
struct _oprnd *op;
{
register int x;
unsigned u1 = 0;
unsigned m1 = 0x0001;
unsigned m2 = 0x8000;
switch (order) {
case '>':
code[2] = op->_reg_list >> 8; /* high byte */
code[3] = op->_reg_list; /* low byte */
return 1;
case '<':
for (x = 15; x >= 0; --x) {
u1 |= (op->_reg_list & (m1 << x)) ? (m2 >> x) : 0;
}
code[2] = u1 >> 8; /* high byte */
code[3] = u1; /* low byte */
return 1;
default:
return ERR_MK;
}
}
/* combined e, f, g, h, and j routines, 12/4/82 */
efghj(arg, i, op)
char arg;
int i;
struct _oprnd *op;
{
int len, displ;
switch (op->_typ) {
case _ani: /* (an) */
if (arg == 'g') {
code[0] |= (op->_reg << 1);
code[1] |= 0x80;
}
else {
code[1] |= (0x10 | op->_reg);
}
return NULL;
case _pd_ani: /* -(an) */
switch (arg) {
case 'g':
code[0] |= (0x01 | op->_reg << 1);
return NULL;
case 'j': return ERR_J;
case 'h': return ERR_H;
default:
code[1] |= (0x20 | op->_reg);
return NULL;
}
case _ani_pi: /* (an)+ */
switch (arg) {
case 'g':
code[0] |= (op->_reg << 1);
code[1] |= 0xc0;
return NULL;
case 'j': return ERR_J;
case 'h': return ERR_H;
default:
code[1] |= (0x18 | op->_reg);
return NULL;
}
case _d16_ani: /* d16(an) */
switch (arg) {
case 'e':
case 'j':
if (/**rorg**/ op->_rel_lbl) {
op->_ireg = op->_reg; /* reg is an index */
op->_iregtyp = op->_regtyp; /* move type */
op->_displ -= (loc_counter + 2); /* make pc relative */
code[1] |= 0x3b;
return _d8_i(i, op); /* indexed label */
}
break;
case 'g':
code[0] |= (0x01 | op->_reg << 1);
code[1] |= 0x40;
return _d16(i, op);
}
code[1] |= (0x28 | op->_reg);
return _d16(i, op);
case _d8_anx: /* d8(an,i) */
if (arg == 'g') {
code[0] |= (0x01 | op->_reg << 1);
code[1] |= 0x80;
}
else {
code[1] |= (0x30 | op->_reg);
}
return _d8_i(i, op);
case _address: /* abs. add., short or long, or label if _rel_lbl */
switch (arg) {
case 'e':
case 'j':
if (/**rorg**/ op->_rel_lbl) {
code[1] |= 0x3a;
op->_displ = op->_addr - (loc_counter + 2); /* rel. to pc */
return _d16(i, op); /* finish as 'label' */
}
break;
case 'g':
code[1] |= 0xc0;
if (op->_long_val) {
code[0] |= 0x03;
code[i++] = op->_addr >> 24;
code[i++] = op->_addr >> 16;
len = 2;